
/*    HTTP Host:  static.ak.fbcdn.net                                          */
/*    Generated:  June 28th 2009 6:30:08 PM PDT                                */
/*      Machine:  10.16.140.101                                                */
/*       Source:  Backing Store                                                */
/*     Location:  js/f051yxtp6i0owg0o.pkg.js h:87jhe03u                        */
/*       Locale:  en_US                                                        */
/*         Path:  js/f051yxtp6i0owg0o.pkg.js                                   */
function ChatBuddyListTypeahead(obj, inputDiv, flid, excludedIds) {
	this.curStr = "";
	this.clearDiv = null;
	this.focused = false;
	this.selected = null;
	this.selectedIndex = 0;
	this.selectableCount = 0;
	this.minBuddyCount = buddyList.flMode ? 20 : 10;
	this.flid = flid;
	this.excludedIds = excludedIds;
	this.id = ChatBuddyListTypeahead.numTypeaheads++;
	this.obj = obj;
	this.obj.typeahead = this;
	this.placeholderText = obj.value;
	this.inputDiv = inputDiv;
	this.shouldShowClear = !presence.isSafari2;
	if (!this.shouldShowClear) {
		obj.onmousedown = this._onmousedown.bind(this);
	}
	addEventBase(this.obj, "focus", this._onfocus.bind(this));
	addEventBase(this.obj, "blur", this._onblur.bind(this));
	addEventBase(this.obj, "keyup", function (e) {
		e = $E(e);
		var keycode = e ? e.keyCode : -1;
		this._onkeyup.bind(this, keycode).defer();
	}.bind(this));
	this.captureSubmit();
	this.buildIndex();
	Arbiter.subscribe(ChatBuddyList.AVAILABILITY_CHANGED, this.buildIndex.bind(this));
}
ChatBuddyListTypeahead.numTypeaheads = 0;
ChatBuddyListTypeahead.mixin({buildIndex:function () {
	this.availableListIDs = buddyList.getSortedListUI(this.flid);
	this.firstLetterIndex = {};
	for (var i = 0; i < this.availableListIDs.length; i++) {
		var id = this.availableListIDs[i];
		var name = typeahead_source.tokenize(chatDisplay.userInfos[id].name);
		for (var token = 0; token < name.length; token++) {
			if (!this.firstLetterIndex[name[token][0]]) {
				this.firstLetterIndex[name[token][0]] = {};
			}
			this.firstLetterIndex[name[token][0]][id] = true;
		}
	}
	this._refreshAvailableList();
	if (buddyList.availableCount < this.minBuddyCount) {
		hide(this.inputDiv);
		this.resetSearch(true);
	} else {
		show(this.inputDiv);
		this.search.bind(this, true).defer();
	}
}, _onfocus:function (e) {
	this.focused = true;
	this.captureSubmit();
}, _onblur:function (e) {
	this.focused = false;
	if (this.curStr == "") {
		this.hideClear();
	}
}, _getAvailableListIDs:function () {
	if (!this.availableIDs) {
		this._refreshAvailableList();
	}
	return this.availableIDs;
}, _refreshAvailableList:function () {
	var ids = this.availableListIDs;
	if (this.excludedIds) {
		ids = ids.filter((function (id) {
			return this.excludedIds[id] != 1;
		}).bind(this));
	}
	this.availableIDs = ids;
}, _onmousedown:function () {
	setTimeout(function () {
		this._onkeyup(0);
	}.bind(this), 100);
}, _onkeyup:function (keycode) {
	switch (keycode) {
	  case KEYS.ESC:
		if ("" == this.curStr) {
			buddyList.closeTab();
		} else {
			this.resetSearch(true);
		}
		break;
	  case undefined:
	  case KEYS.LEFT:
	  case KEYS.RIGHT:
		return false;
		break;
	  case KEYS.UP:
		this.upArrowPress();
		break;
	  case KEYS.DOWN:
		this.downArrowPress();
		break;
	  case KEYS.RETURN:
		this.select();
		break;
	  case KEYS.BACKSPACE:
	  case 0:
	  default:
		if (this.search()) {
			this.resetSearch(true);
		}
		break;
	}
}, focusInput:function () {
	if (buddyList.availableCount && buddyList.availableCount > this.minBuddyCount) {
		this.obj.focus();
	}
	this.resetSearch();
}, captureSubmit:function () {
	if ((!this.capturedForm || this.capturedSubstitute != this.capturedForm.onsubmit) && this.obj.form) {
		this.capturedForm = this.obj.form;
		this.captured_event = this.obj.form.onsubmit;
		this.capturedSubstitute = this.obj.form.onsubmit = function () {
			return false;
		}.bind(this.obj.form);
	}
}, resetSearch:function (clear) {
	if (!this.obj) {
		return false;
	}
	if (!this.obj.value || clear) {
		this.curStr = "";
		this.obj.value = "";
		this.hideClear();
	}
	this.selected = null;
	this.selectedIndex = -1;
	this.showAll();
	this.hideClear();
	buddyList.unfreezeTabSize();
}, search:function (force) {
	var value = this.obj.value;
	if (value == this.placeholderText) {
		return true;
	}
	var str = typeahead_source.flatten_string(value);
	if (!force && str == this.curStr) {
		return false;
	}
	this.curStr = str;
	var tokenizedStr = typeahead_source.tokenize(str).sort(typeahead_source._sort);
	if (!tokenizedStr[0]) {
		return true;
	}
	var quickIndex = this.firstLetterIndex[tokenizedStr[0][0]];
	buddyList.freezeTabSize();
	this.showClear();
	buddyList.suppressNonFriendInfoInBuddyList(this.flid);
	this.getMatchingFriends(quickIndex, tokenizedStr);
	this.selected = null;
	this.selectMatchingFriends();
	return false;
}, getMatchingFriends:function (quickIndex, tokenizedStr) {
	var matches = 0;
	var firstMatch;
	var availableListIDs = this._getAvailableListIDs();
	for (var i = 0; i < availableListIDs.length; i++) {
		var id = availableListIDs[i];
		var fullName = chatDisplay.userInfos[id].name;
		if (quickIndex != undefined && quickIndex[id] && typeahead_source.check_match(tokenizedStr, fullName)) {
			var name = typeahead_source.highlight_found(fullName, this.curStr);
			buddyList.getBuddyItemName(id, this.flid).setContent(HTML(name));
			buddyList.showBuddyItem(id, false, this.flid);
			matches++;
			if (!firstMatch) {
				firstMatch = id;
			}
		} else {
			CSS.removeClass(buddyList.getBuddyItem(id, this.flid), "selected");
			buddyList.hideBuddy(id, this.flid);
		}
	}
	if (matches > 0) {
		buddyList.hideEmptySearch(this.flid);
		if (matches == 1 || (tokenizedStr.length == 1 && tokenizedStr[0].length == 1)) {
			this.selected = firstMatch;
			this.selectedIndex = 0;
			CSS.addClass(buddyList.getBuddyItem(firstMatch, this.flid), "selected");
		}
	} else {
		buddyList.showEmptySearch(this.flid);
	}
}, selectMatchingFriends:function () {
	this.selectableCount = 0;
	var availableListIDs = this._getAvailableListIDs();
	for (var i = 0; i < availableListIDs.length; i++) {
		var id = availableListIDs[i];
		var buddy = buddyList.getBuddyItem(id, this.flid);
		if (buddy && CSS.getStyle(buddy, "display") != "none") {
			if (this.selectedIndex == this.selectableCount) {
				this.selected = id;
				CSS.addClass(buddy, "selected");
				Vector2.scrollIntoView(buddy);
			} else {
				CSS.removeClass(buddy, "selected");
			}
			this.selectableCount++;
		}
	}
}, downArrowPress:function () {
	this.selectedIndex++;
	var max = this.selectableCount - 1;
	if (this.selectedIndex > max) {
		this.resetSearch();
	}
	this.selectMatchingFriends();
}, upArrowPress:function () {
	this.selectedIndex--;
	if (this.selectedIndex < 0) {
		this.selectedIndex = 0;
	}
	this.selectMatchingFriends();
}, showAll:function () {
	this.obj.value = "";
	buddyList.hideEmptySearch(this.flid);
	var availableListIDs = this._getAvailableListIDs();
	for (var i = 0; i < availableListIDs.length; i++) {
		var id = availableListIDs[i];
		var buddy = buddyList.getBuddyItem(id, this.flid);
		if (buddy) {
			buddyList.updateBuddyItemName(id, this.flid);
			CSS.removeClass(buddyList.getBuddyItem(id, this.flid), "selected");
			buddyList.showBuddyItem(id, true, this.flid);
		}
	}
	buddyList.unsuppressNonFriendInfoInBuddyList(this.flid);
}, showClear:function () {
	if (this.clearDiv == null && this.shouldShowClear) {
		this.clearDiv = document.createElement("div");
		this.clearDiv.setAttribute("id", "clear_search" + this.id);
		DOM.setContent(this.clearDiv, HTML("<a href=\"#\" class=\"hide\"></a>"));
		var link = DOM.find(this.clearDiv, "a");
		link.listen("click", (function () {
			this.resetSearch(true);
			return false;
		}).bind(this));
		this.inputDiv.appendChild(this.clearDiv);
	}
}, hideClear:function () {
	if (ge("clear_search" + this.id)) {
		this.clearDiv = null;
		this.inputDiv.removeChild(ge("clear_search" + this.id));
	}
}, select:function () {
	if (this.selected != null) {
		CSS.removeClass(buddyList.getBuddyItemName(this.selected, this.flid), "selected");
		buddyList.itemOnClick(this.selected, this.flid);
		this.resetSearch(true);
	}
}});
function ChatBuddyList() {
	this.user = presence.user;
	this.shouldRender = true;
	this.haveFullList = false;
	this.errorMode = false;
	this.shouldShowLoading = false;
	this.availableCount = 0;
	this.availableList = {};
	this.sortedList = [];
	this.listChanged = false;
	this.updateTime = 0;
	this.flMode = false;
	this.flData = {};
	this.otherFriendsFlid = "-1";
	this.botsFlid = "-2";
	this.stopUpdates = false;
	this.flSortableGroup = null;
	this.reorderingLists = false;
	this.sortables = {};
	this.flOpts = {};
	this.externalFlids = [];
	this.updateOverlay = {};
	this.visibilityRatio = {};
	this.justCameOnline = false;
	this.maxNameLen = 20;
	this.maxStatusLen = presence.inPopoutWindow ? 22 : 28;
	this.backgroundColor = presence.inPopoutWindow ? "#f7f7f7" : "#fff";
}
copy_properties(ChatBuddyList, {OVERLAY_ONLINE:0, OVERLAY_IDLE:1, OVERLAY_OFFLINE:-1, DEFAULT_OPTS:{fullDisplay:true, showStatuses:true, excludeIds:{}}, BUDDY_LIST_INITIALIZED:"buddylist/initialized", BUDDY_CLICKED:"buddylist/buddy_clicked", AVAILABILITY_CHANGED:"buddylist/availability-changed", UPDATER_NAME:"buddy_list"});
ChatBuddyList.prototype = {maxItemsToAnimate:10, highlightColor:"#fffbe2", expandAnimDuration:400, compactItemHeight:18, fullItemHeight:26, initError:function () {
	this.errorMode = true;
	this._init();
}, initNoRender:function (availableCount, availableList, updateTime, listChanged, flMode, flData, updateOverlay) {
	this.shouldRender = false;
	this.shouldShowLoading = true;
	this.availableCount = availableCount;
	this.availableList = availableList;
	this.updateTime = updateTime;
	this.listChanged = listChanged;
	this.updateOverlay = updateOverlay;
	this.flMode = flMode;
	this.flData = flData;
	this._init();
	if (presence.inPopoutWindow) {
		this._forceUpdate.bind(this, false).defer();
	}
}, initFullList:function (availableList, updateTime, listChanged, flMode, flData, updateOverlay) {
	this.availableList = availableList;
	this.updateTime = updateTime;
	this.listChanged = listChanged;
	this.haveFullList = true;
	this.flMode = flMode;
	this.flData = flData;
	this.updateOverlay = updateOverlay;
	this.availableCount = count(this.availableList);
	this._init();
}, _init:function () {
	this.availabilityHandlers = [];
	this.loaded = false;
	this.poppedOut = presence.poppedOut;
	this.buddyListOpen = false;
	this.clickedClosed = false;
	this.clickedOpen = false;
	this.updateDiff = 0;
	this.rendered = false;
	this.showingError = false;
	this.numRequestFailures = 0;
	for (var id in this.availableList) {
		this.availableList[id].i = this.availableList[id].i ? 1 : 0;
	}
	this.tabID = "buddy_list_tab";
	this.wrapperID = "buddy_list";
	this.contentID = "buddy_list_content";
	this.tabDiv = ge(this.tabID);
	this.wrapperDiv = ge(this.wrapperID);
	this.contentDiv = ge(this.contentID);
	this.buddyListError = ge("buddy_list_error");
	this.buddyCountSpan = ge("buddy_count");
	presenceUpdater.register(ChatBuddyList.UPDATER_NAME, this._checkUpdater.bind(this), this._onUpdaterResponse.bind(this), this._onUpdaterError.bind(this), this._onUpdaterError.bind(this));
	presenceCookieManager.register("bl", this._getCookieData.bind(this));
	presence.registerStateStorer(this._storeState.bind(this));
	presence.registerStateLoader(this._loadState.bind(this));
	Arbiter.subscribe(Presence.TAB_OPENED, this._tabOpened.bind(this));
	Arbiter.subscribe(Presence.getArbiterMessageType("fl_settings"), this._handleFLMessage.bind(this));
	Arbiter.subscribe(ChatOptions.VISIBILITY_CHANGED, this._handleVisibility.bind(this));
	this.setCompactDisplay(chatOptions.getSetting("compact_buddylist"));
	this._loadState(presence.state);
	this._postInit.bind(this).defer();
	Arbiter.subscribe(Arbiter.LIST_EDITOR_LISTS_CHANGED, this._flManagerHandler.bind(this));
}, _postInit:function () {
	if (presence.inPopoutWindow) {
		this._firstRender();
	}
	if (chatOptions.visibility) {
		this._updateCount();
	}
	this.updateDiff = this._computeUpdateTimeDiff();
	this._mergeOverlay();
	Arbiter.inform(ChatBuddyList.BUDDY_LIST_INITIALIZED, {}, Arbiter.BEHAVIOR_PERSISTENT);
}, _storeState:function (presenceState) {
	presenceState.blo = this.buddyListOpen ? 1 : 0;
	presenceState.bvt = parseInt(this.buddyViewTime * 0.001);
	return presenceState;
}, _loadState:function (presenceState) {
	this.buddyViewTime = verifyNumber(presenceState.bvt) * 1000;
	var openBuddyList = !!presenceState.blo;
	if (!presence.poppedOut && this.poppedOut) {
		this._showLoading();
		this._forceUpdate(false);
	}
	this.poppedOut = presence.poppedOut;
	var fn = null;
	if (!this.poppedOut) {
		if (openBuddyList) {
			fn = this.openTab.bind(this);
		} else {
			fn = this.closeTab.bind(this);
		}
	}
	if (fn) {
		if (this.loaded) {
			fn();
		} else {
			fn.defer();
		}
	}
	this.loaded = true;
}, setCompactDisplay:function (isCompact) {
	this.isCompactDisplay = isCompact;
	if (this.isCompactDisplay) {
		this.itemHeight = this.compactItemHeight;
	} else {
		this.itemHeight = this.fullItemHeight;
	}
	if (this.rendered) {
		this._render();
	}
}, _handleVisibility:function () {
	if (chatOptions.visibility) {
		this._showLoading();
		this._show();
		this._forceUpdate(true);
		this.justCameOnline = true;
	} else {
		this._hide();
	}
}, _handleFLMessage:function (type, data) {
	var obj = data.obj;
	this.setVisibilityRatio({});
	if (!this._flChanged(obj.fl_mode, obj.fl_data)) {
		return;
	}
	this._onFlChange(obj.fl_mode, obj.fl_data);
}, _flChanged:function (newFlMode, newFlData) {
	return (newFlMode != this.flMode || !are_equal(newFlData, this.flData));
}, _massageNowAvailableList:function (nowAvailableList, newFlMode, newFlData) {
	for (var id in nowAvailableList) {
		var buddyInfo = nowAvailableList[id];
		if (newFlMode != this.flMode) {
			if (newFlMode) {
				delete buddyInfo.fl;
			} else {
				buddyInfo["fl"] = [this.otherFriendsFlid];
			}
		} else {
			var flids = buddyInfo.fl || [];
			for (var i = 0; i < flids.length; i++) {
				var flid = flids[i];
				if (typeof this.flData[flid] == "undefined") {
					buddyInfo.fl.remove(flid);
				}
			}
			if (buddyInfo.fl && buddyInfo.fl.length == 0) {
				buddyInfo.fl = [this.otherFriendsFlid];
			}
		}
		nowAvailableList[id] = buddyInfo;
	}
	return nowAvailableList;
}, _onFlChange:function (newFlMode, newFlData) {
	if (!this.rendered) {
		this.flMode = newFlMode;
		this.flData = newFlData;
		return;
	}
	var toAddFlids = [];
	var toRemoveFlids = [];
	var onlineFlids = [];
	var offlineFlids = [];
	if (this.flMode && this.flMode == newFlMode) {
		var groupedList = this._groupAvailableListByFl(true);
		for (var flid in newFlData) {
			if (typeof this.flData[flid] == "undefined") {
				if (newFlData[flid].h) {
					continue;
				}
				toAddFlids.push(flid);
				onlineFlids.push(flid);
			} else {
				if (this.flData[flid].h != newFlData[flid].h) {
					if (newFlData[flid].h) {
						toRemoveFlids.push(flid);
					} else {
						toAddFlids.push(flid);
						if (newFlData[flid].o) {
							onlineFlids.push(flid);
						}
					}
				} else {
					if (this.flData[flid].o != newFlData[flid].o) {
						if (newFlData[flid].o) {
							onlineFlids.push(flid);
						} else {
							offlineFlids.push(flid);
						}
					}
				}
			}
		}
		for (var flid in this.flData) {
			if (typeof newFlData[flid] == "undefined") {
				toRemoveFlids.push(flid);
			}
		}
		this.flMode = newFlMode;
		if (toRemoveFlids.length != 0) {
			this._removeFlidsFromBuddyList(toRemoveFlids, groupedList);
		}
		if (offlineFlids.length != 0) {
			this._goOfflineToLists(offlineFlids, true);
		}
		this.flData = newFlData;
		if (toAddFlids.length != 0) {
			this._addFlidsToDOM(toAddFlids, groupedList);
		}
		if (onlineFlids.length != 0) {
			this._goOnlineToLists(onlineFlids, true);
		}
	} else {
		if (this.flMode && this.flMode != newFlMode) {
			var groupedList = this._groupAvailableListByFl(true);
			toRemoveFlids = keys(this.flData);
			this.flMode = newFlMode;
			this.flData = newFlData;
			this._addFlidsToDOM([null]);
			this._removeFlidsFromBuddyList(toRemoveFlids, groupedList);
			this._forceUpdate(false);
		} else {
			for (var flid in newFlData) {
				if (newFlData[flid].h) {
					continue;
				}
				toAddFlids.push(flid);
				if (newFlData[flid].o) {
					onlineFlids.push(flid);
				}
			}
			this.flMode = newFlMode;
			this.flData = newFlData;
			this._removeFlidsFromDOM([null]);
			if (toAddFlids.length > 0) {
				this._addFlidsToDOM(toAddFlids);
			}
			if (onlineFlids.length > 0) {
				this._goOnlineToLists.bind(this, onlineFlids, true).defer();
			}
		}
	}
}, _addFlidsToDOM:function (flids, groupedList) {
	groupedList = groupedList || this._groupAvailableListByFl(true);
	var allFlids = this._getRenderedFriendLists();
	var firstFlid = allFlids[0];
	var parentOfThemAll = $("buddy_list_parent");
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		if (this.flMode && flid) {
			var elem = DOM.create("li", {"id":this._getFriendListId(flid), "className":this._getFriendListItemClasses(flid, groupedList)});
			DOM.setContent(elem, HTML(this._renderFriendListHeader(flid)));
			DOM.appendContent(elem, HTML(this._renderFriendListContent(flid, [])));
			if (firstFlid == flid) {
				parentOfThemAll.prependContent(elem);
			} else {
				var prevIndex = allFlids.indexOf(flid);
				var prevFlid = allFlids[prevIndex - 1];
				DOM.insertAfter(ge(this._getFriendListId(prevFlid)), elem);
			}
			this._addFlSortable(flid);
			this._initFlidSortable(flid, []);
		} else {
			parentOfThemAll.prependContent(HTML(this._renderFriendListContent(null, [])));
		}
	}
	this._addFriendListListeners(flids);
}, _removeFlidsFromDOM:function (flids) {
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		if (flid) {
			if (ge(this._getFriendListId(flid))) {
				DOM.remove($(this._getFriendListId(flid)));
				this._removeFlSortable(flid);
				this._destroyFlidSortable(flid);
			}
		} else {
			DOM.remove($(this._getAvailableMarkerId(flid)));
			DOM.remove($(this._getIdleMarkerId(flid)));
		}
	}
}, loadTypeahead:function () {
	this.typeahead = new ChatBuddyListTypeahead($("buddy_list_typeahead_input"), $("buddy_list_typeahead"));
}, getContentWrapper:function () {
	return this.contentDiv.parentNode;
}, resizeTab:function (force) {
	if (this.resizeFrozen) {
		if (force) {
			this.resizeFrozen = false;
		} else {
			return;
		}
	}
	presence.tabContentResize(this.wrapperID, this.contentID);
}, freezeTabSize:function (forceLockHeight) {
	if (this.resizeFrozen || this.showingError) {
		return;
	}
	this.resizeFrozen = true;
	if (forceLockHeight === undefined) {
		forceLockHeight = true;
	}
	presence.tabContentResize(this.wrapperID, this.contentID, forceLockHeight);
}, unfreezeTabSize:function () {
	if (!this.resizeFrozen) {
		return;
	}
	this.resizeFrozen = false;
	this.resizeTab();
	presence.contentChanged(this.contentID);
}, _hide:function () {
	if (presence.inPopoutWindow) {
		CSS.addClass(presence.popoutSidebar, "buddy_list_hidden");
	} else {
		CSS.addClass(presence.holder, "buddy_list_hidden");
		this.closeTab();
		DOM.setContent(this.buddyCountSpan, _tx("Chat (Offline)"));
	}
}, _show:function () {
	if (presence.inPopoutWindow) {
		CSS.removeClass(presence.popoutSidebar, "buddy_list_hidden");
	} else {
		CSS.removeClass(presence.holder, "buddy_list_hidden");
		this.openTab();
		this._updateCount();
	}
}, toggleTab:function () {
	if (!this.buddyListOpen) {
		this.clickedOpen = true;
		this.openTab(true);
	} else {
		this.clickedClosed = true;
		this.closeTab();
	}
}, _goOnline:function () {
	chatOptions.sendVisibility(true);
}, openTab:function (focusTypeahead) {
	if (this.buddyListOpen) {
		return;
	}
	if (CSS.hasClass(presence.holder, "buddy_list_hidden")) {
		this._goOnline();
		return;
	}
	if (!this.rendered) {
		var availableList = this.availableList;
		this.availableList = {};
		this.shouldShowLoading = true;
		this._firstRender();
		presence.openTab(this.wrapperID, this.tabID);
		this.availableList = availableList;
		if (this.haveFullList) {
			this._render.bind(this).defer();
			setTimeout(this._availableListChanged.bind(this, true), 10);
		}
	} else {
		presence.openTab(this.wrapperID, this.tabID, this.contentID);
	}
	this.buddyListOpen = true;
	setTimeout(this._openTabPostProcess.bind(this, focusTypeahead), 50);
}, _openTabPostProcess:function (focusTypeahead) {
	this.buddyViewTime = (new Date()).getTime();
	var sinceLastUpdate = (presence.getTime() - this.updateTime) * 0.001;
	if (this.showingError || sinceLastUpdate > presence.sitevars.BUDDY_VIEW_FETCH_WINDOW) {
		this._forceUpdate(false);
	}
	presence.doSync();
	if (focusTypeahead && this.typeahead) {
		this.typeahead.focusInput();
	}
}, closeTab:function () {
	if (!this.buddyListOpen) {
		return;
	}
	this.buddyListOpen = false;
	presence.toggleTab(this.wrapperID, this.tabID, this.contentID);
	if (chatOptions.visibility) {
		setTimeout(this._closeTabPostProcess.bind(this), 50);
	}
	buddyListDisplay.closeOpenFlyout();
	this.exitReorderingFlMode();
}, _closeTabPostProcess:function () {
	if (this.typeahead) {
		this.typeahead.resetSearch(true);
	}
	this.buddyViewTime = (new Date()).getTime();
	presence.doSync();
}, _tabOpened:function () {
	if (!this.buddyListOpen) {
		return;
	}
	this.buddyListOpen = false;
	this.buddyViewTime = (new Date()).getTime();
	presence.doSync();
}, _mergeOverlay:function () {
	if (!this.haveFullList) {
		return;
	}
	var time = presence.getTime();
	var nowAvail = {};
	var wasAvail = [];
	for (var id in this.updateOverlay) {
		if (time < this.updateOverlay[id].exp) {
			var buddyInfo = this.availableList[id];
			if (!chatDisplay.userInfos[id]) {
				continue;
			}
			if (this.updateOverlay[id].ol != ChatBuddyList.OVERLAY_OFFLINE) {
				if (!buddyInfo) {
					buddyInfo = {i:0};
					if (this.flMode) {
						buddyInfo.fl = [this.otherFriendsFlid];
					}
					nowAvail[id] = buddyInfo;
				} else {
				}
			} else {
				wasAvail.push(id);
			}
		} else {
			delete this.updateOverlay[id];
		}
	}
	if (!is_empty(nowAvail) || !is_empty(wasAvail)) {
		this._updateAvailableListWithDiff(nowAvail, wasAvail);
	}
}, getAvailability:function (id) {
	if (id == this.user) {
		return chatOptions.visibility;
	}
	if (typeof this.availableList[id] != "undefined") {
		return this.availableList[id];
	} else {
		return null;
	}
}, setAvailable:function (id, keepIdle) {
	this._manageOverlay(id, ChatBuddyList.OVERLAY_ONLINE);
	this._addToBuddyList([id], keepIdle);
}, _addToBuddyList:function (ids, keepIdle) {
	var availDiff = {};
	var wasAvail = [];
	for (var i = 0; i < ids.length; i++) {
		var id = ids[i];
		var availability = this.getAvailability(id);
		if (availability && (availability.i == 0 || keepIdle)) {
			continue;
		}
		availDiff[id] = {i:0};
		if (this.flMode) {
			if (this.availableList[id] && this.availableList[id].fl) {
				availDiff[id]["fl"] = this.availableList[id].fl;
			} else {
				availDiff[id]["fl"] = [this.otherFriendsFlid];
			}
		}
		if (availability && availability.i == 1) {
			wasAvail.push(id);
		}
	}
	this._updateAvailableListWithDiff(availDiff, wasAvail);
}, setFlids:function (id, flids) {
	if (!this.getAvailability(id)) {
		return;
	}
	if (this.availableList[id].fl[0] == this.otherFriendsFlid) {
		var nowAvail = {};
		nowAvail[id] = this.availableList[id];
		nowAvail[id]["fl"] = flids;
		this._updateAvailableListWithDiff(nowAvail, [], this.otherFriendsFlid);
	}
}, setUnavailable:function (id) {
	this._manageOverlay(id, ChatBuddyList.OVERLAY_OFFLINE);
	this._removeFromBuddyList([id]);
}, _removeFromBuddyList:function (ids, flid) {
	var toRemove = [];
	for (var i = 0; i < ids.length; i++) {
		var id = ids[i];
		if (!this.getAvailability(id)) {
			continue;
		}
		toRemove.push(id);
	}
	if (toRemove.length > 0) {
		this._updateAvailableListWithDiff({}, toRemove, flid);
	}
}, addOverlayInfo:function (overlay) {
	for (var id in overlay) {
		this._manageOverlay(id, overlay[id].ol);
	}
	this._mergeOverlay();
}, _manageOverlay:function (id, new_state) {
	var exp = presence.getTime() + 60000;
	this.updateOverlay[id] = {"ol":new_state, "exp":exp};
	if (this.rendered) {
		presenceCookieManager.store();
	}
}, hideBuddy:function (id, flid) {
	var flids;
	if (flid) {
		flids = [flid];
	} else {
		flids = this._getUserFlids(id, null, true);
	}
	this._toggleBuddy(id, false, flids);
}, _toggleBuddy:function (id, show, flids) {
	var newDisplay = show ? "block" : "none";
	var listItem, flItem;
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		listItem = ge(this._getBuddyListItemId(id, flid));
		if (listItem) {
			listItem.style.display = newDisplay;
		}
		if (show && (flItem = ge(this._getFriendListId(flid)))) {
			CSS.removeClass(flItem, "suppress");
		}
	}
}, showBuddyItem:function (id, showAll, flid) {
	showAll = showAll || false;
	var flids;
	if (flid) {
		flids = [flid];
	} else {
		var flids = this._getUserFlids(id, null, true);
		if (flids.length > 1 && !showAll) {
			var hideFlids = flids.slice(1);
			this._toggleBuddy(id, false, hideFlids);
			flids = [flids[0]];
		}
	}
	this._toggleBuddy(id, true, flids);
}, getBuddyItem:function (id, flid) {
	flid = this._getUserFlid(id, flid);
	return ge(this._getBuddyListItemId(id, flid));
}, getBuddyItemName:function (id, flid) {
	flid = this._getUserFlid(id, flid);
	return ge(this._getBuddyListItemNameId(id, flid));
}, updateBuddyItemName:function (id, flid) {
	var userInfo = chatDisplay.userInfos[id];
	var name = userInfo.name;
	var nameCapped;
	if (name.length > this.maxNameLen) {
		nameCapped = name.substring(0, this.maxNameLen - 2) + "...";
	} else {
		nameCapped = name;
	}
	this.getBuddyItemName(id, flid).innerHTML = nameCapped;
}, _getUserFlid:function (id, flid) {
	if (flid === null || flid === undefined) {
		var flids = this._getUserFlids(id);
		flid = flids[0];
	}
	return flid;
}, showEmptySearch:function (flid) {
	show(this._getEmptySearchId(flid));
}, hideEmptySearch:function (flid) {
	hide(this._getEmptySearchId(flid));
}, _getSortedList:function () {
	if (this.sortedList.length == 0 && count(this.availableList) == this.availableCount) {
		this.sortedList = this._sort(keys(this.availableList));
	}
	return this.sortedList;
}, getSortedListUI:function (flid) {
	if (!flid && this.flMode) {
		var groupedList = this._groupAvailableListByFl(true);
		var list = [];
		for (var flid in groupedList) {
			list = list.concat(groupedList[flid]);
		}
		return unique(list);
	}
	return this._getSortedList();
}, getFriendLists:function () {
	var res = {};
	copy_properties(res, this.flData);
	delete res[this.otherFriendsFlid];
	delete res[this.botsFlid];
	return res;
}, _getRenderedFriendLists:function () {
	var flids = [];
	for (var flid in this.flData) {
		if (!this.flData[flid].h) {
			flids.push(flid);
		}
	}
	return flids;
}, _getFriendListsInChat:function () {
	var flids = this._getRenderedFriendLists();
	flids.remove(this.otherFriendsFlid);
	flids.remove(this.botsFlid);
	return flids;
}, suppressNonFriendInfoInBuddyList:function (flid) {
	this._updateNonFriendInfoInBuddyList(flid, true);
}, unsuppressNonFriendInfoInBuddyList:function (flid) {
	this._updateNonFriendInfoInBuddyList(flid, false);
}, _updateNonFriendInfoInBuddyList:function (flid, suppress) {
	var flids = flid ? [flid] : this._getGlobalFlids(true);
	var idleMarker, flItem;
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		if (idleMarker = ge(this._getIdleMarkerId(flid))) {
			CSS.conditionClass(idleMarker, "suppress", suppress);
		}
		if (flid && (flItem = ge(this._getFriendListId(flid)))) {
			CSS.conditionClass(flItem, "suppress", suppress);
		}
	}
}, _updateCount:function () {
	if (this.buddyCountSpan) {
		var countText = _tx("{Chat} {number-available}", {"Chat":_tx("Chat"), "number-available":"<span class=\"buddy_count_num\">(<strong>" + this.availableCount + "</strong>)</span>"});
		this.buddyCountSpan.innerHTML = countText;
	}
}, setVisibilityRatio:function (cvr) {
	this.visibilityRatio = cvr;
	presence.doSync();
}, _getCookieData:function () {
	var availableListCache = {};
	for (var id in chatDisplay.tabs) {
		if (this.availableList[id]) {
			availableListCache[id] = this.availableList[id];
		}
	}
	var buddyState = {"ac":this.availableCount, "al":availableListCache, "ut":parseInt(this.updateTime * 0.001), "ud":parseInt(this.updateDiff), "lc":this.listChanged ? 1 : 0, "uo":this.updateOverlay, "cvr":this.visibilityRatio};
	return buddyState;
}, _computeUpdateTimeDiff:function () {
	if (!chatOptions.visibility || (presence.poppedOut && !presence.inPopoutWindow)) {
		return Math.round(presence.sitevars.BUDDY_MAX_TIME);
	}
	var newUpdateTime = presence.sitevars.BUDDY_BASE_TIME;
	var now = presence.getTime();
	if (!chatDisplay.everSentMessage) {
		newUpdateTime += presence.sitevars.BUDDY_COST_NEVER_SENT_MESSAGE;
	}
	if (!this.listChanged) {
		newUpdateTime += presence.sitevars.BUDDY_COST_NO_LIST_CHANGE;
	}
	if (chatTabSlider.numTabs == 0) {
		newUpdateTime += presence.sitevars.BUDDY_COST_NO_CHAT_TABS;
	}
	var chatActivityMins = (now - chatDisplay.chatActivityTime) / 60000;
	if (chatActivityMins > presence.sitevars.BUDDY_MAX_ACTIVITY_MINS) {
		chatActivityMins = presence.sitevars.BUDDY_MAX_ACTIVITY_MINS;
	}
	newUpdateTime += (presence.sitevars.BUDDY_COST_CHAT_ACTIVITY / presence.sitevars.BUDDY_MAX_ACTIVITY_MINS) * chatActivityMins;
	if (!presence.poppedOut) {
		var pageLoadMins = (now - presence.pageLoadTime) / 60000;
		if (pageLoadMins < chatActivityMins) {
			if (pageLoadMins > presence.BUDDY_MAX_ACTIVITY_MINS) {
				pageLoadMins = presence.BUDDY_MAX_ACTIVITY_MINS;
			}
			newUpdateTime += (presence.sitevars.BUDDY_COST_PAGE_ACTIVITY / presence.sitevars.BUDDY_MAX_ACTIVITY_MINS) * pageLoadMins;
		}
		if (!this.buddyListOpen) {
			var buddyViewMins = (now - this.buddyViewTime) / 60000;
			if (buddyViewMins > presence.sitevars.BUDDY_MAX_ACTIVITY_MINS) {
				buddyViewMins = presence.sitevars.BUDDY_MAX_ACTIVITY_MINS;
			}
			newUpdateTime += (presence.sitevars.BUDDY_COST_VIEW_ACTIVITY / presence.sitevars.BUDDY_MAX_ACTIVITY_MINS) * buddyViewMins;
		}
	}
	if (!newUpdateTime || newUpdateTime > presence.sitevars.BUDDY_MAX_TIME) {
		newUpdateTime = presence.sitevars.BUDDY_MAX_TIME;
	}
	return Math.round(newUpdateTime);
}, _checkUpdater:function (time, asyncData, forceUpdate) {
	this.updateDiff = this._computeUpdateTimeDiff();
	if (forceUpdate || (!this.stopUpdates && (time - this.updateTime) > this.updateDiff * 1000)) {
		asyncData.popped_out = presence.poppedOut;
		asyncData.available_list = this.haveFullList ? this.availableList : {};
		asyncData.force_render = this.shouldRender;
		return true;
	}
}, _forceUpdate:function (forceAll) {
	this.shouldRender = true;
	var handlers = forceAll ? undefined : [ChatBuddyList.UPDATER_NAME];
	presenceUpdater.forceUpdate(handlers);
}, updateUserInfos:function (userInfos) {
	for (var id in userInfos) {
		var userInfo = userInfos[id];
		var statusChanged = (!chatDisplay.userInfos[id] || userInfo.status != chatDisplay.userInfos[id].status);
		var shouldUpdate = (statusChanged || userInfo.statusTimeRel != chatDisplay.userInfos[id].statusTimeRel);
		chatDisplay.userInfos[id] = userInfos[id];
		if (shouldUpdate) {
			this.updateItemDisplay(id);
			if (chatDisplay.tabs[id]) {
				chatDisplay.tabs[id].updateUserInfo();
			}
		}
	}
}, _collapseItem:function (id, buddyInfo, shouldAnimate, flid) {
	if (this.flMode && flid) {
		var flids = [flid];
	} else {
		var flids = this._getUserFlids(id, buddyInfo);
	}
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		var elem = ge(this._getBuddyListItemId(id, flid));
		if (elem) {
			elem.id = this._getBuddyListWasItemId(id, flid);
			if (shouldAnimate) {
				animation(elem).to("height", "0px").duration(this.expandAnimDuration).go();
			}
			this._removeSortable(id, flids[i]);
		}
	}
}, _expandItem:function (id, flid, prevElem, isIdle, shouldAnimate, shouldDelayExpand, showHighlight) {
	var elem = ge(this._getBuddyListItemId(id, flid));
	if (!elem) {
		var elem = document.createElement("li");
		elem.id = this._getBuddyListItemId(id, flid);
	}
	if (isIdle) {
		CSS.setClass(elem, "idle");
	}
	elem.innerHTML = this._renderItem(id, flid, isIdle);
	var itemHeight = (this.isCompactDisplay ? this.compactItemHeight : this.itemHeight);
	var opts = this._getFlOpts(flid);
	if (!opts.fullDisplay) {
		itemHeight = this.compactItemHeight;
	}
	if (!shouldAnimate) {
		elem.style.height = itemHeight + "px";
		DOM.insertAfter(prevElem, elem);
	} else {
		elem.style.height = "0px";
		DOM.insertAfter(prevElem, elem);
		var anim = animation(elem);
		if (shouldDelayExpand) {
			anim.duration(this.expandAnimDuration + 500).checkpoint();
		}
		anim.from("height", "0").to("height", itemHeight + "px").duration(this.expandAnimDuration);
		if (showHighlight === undefined) {
			showHighlight = !isIdle;
		}
		if (showHighlight) {
			elem.style.backgroundColor = this.highlightColor;
			anim.checkpoint().duration(3000).checkpoint().to("backgroundColor", this.backgroundColor).duration(500);
		}
		anim.go();
	}
	this._addSortable(id, flid);
	return elem;
}, _clearWasAvailableItems:function (wasAvailableIDs, wasAvailableList, flid) {
	if (!this.rendered) {
		return;
	}
	for (var i = 0; i < wasAvailableIDs.length; i++) {
		var id = wasAvailableIDs[i];
		if (wasAvailableList[id]) {
			if (this.flMode && flid) {
				var flids = [flid];
			} else {
				var flids = this._getUserFlids(id, wasAvailableList[id]);
			}
			for (var j = 0; j < flids.length; j++) {
				var elem = ge(this._getBuddyListWasItemId(id, flids[j]));
				if (elem) {
					DOM.remove(elem);
					delete elem;
				}
			}
		}
	}
	this._showBuddyListEmptyItem();
}, _showBuddyListEmptyItem:function () {
	var emptyItem = ge(this._getBuddyListEmptyItemId());
	if (emptyItem) {
		CSS.conditionClass(emptyItem, "hide_empty_item", this.availableCount != 0);
	}
}, _hideBuddyListEmptyItem:function () {
	var emptyItem = ge(this._getBuddyListEmptyItemId());
	if (emptyItem) {
		CSS.addClass(emptyItem, "hide_empty_item");
	}
}, _updateAvailableListWithDiff:function (nowAvailableList, wasAvailableIDs, flid) {
	if (this.stopUpdates) {
		return;
	}
	var id, isIdle;
	var shouldDelayExpand = false;
	var wasAvailableList = {};
	var wasAvailableMultipleLists = {};
	var filterExternalFlids = (flid != null);
	for (var i = 0; i < wasAvailableIDs.length; i++) {
		var uid = wasAvailableIDs[i];
		if (this.availableList[uid]) {
			shouldDelayExpand = true;
			wasAvailableList[wasAvailableIDs[i]] = this.availableList[uid];
			if (flid && this.flMode && this.availableList[uid].fl.length > 1) {
				this.availableList[uid].fl.remove(flid);
				wasAvailableMultipleLists[uid] = 1;
				continue;
			}
			delete this.availableList[uid];
		}
	}
	this._hideBuddyListEmptyItem();
	var nowAvailableIDs = keys(nowAvailableList);
	var shouldAnimate = !flid && !this.showingError && !presence.isSafari2 && (wasAvailableIDs.length + nowAvailableIDs.length < this.maxItemsToAnimate);
	if (this.rendered) {
		for (var i = 0; i < wasAvailableIDs.length; i++) {
			if (wasAvailableList[wasAvailableIDs[i]]) {
				this._collapseItem(wasAvailableIDs[i], wasAvailableList[wasAvailableIDs[i]], shouldAnimate, flid);
			}
		}
		var clearDelay = shouldAnimate ? this.expandAnimDuration : 0;
		setTimeout(this._clearWasAvailableItems.bind(this, wasAvailableIDs, wasAvailableList, flid), clearDelay);
	}
	var availableIDs = this.sortedList;
	if (this.haveFullList) {
		this.sortedList = [];
	}
	this._sort(nowAvailableIDs, nowAvailableList);
	var nowAvailableID = nowAvailableIDs.shift();
	var availableID = availableIDs.shift();
	var compareFunction = this._compareFunction.bind(this, null);
	var defaultPrevAvailElemIds = {}, prevIdleElemIds = {}, prevAvailElemIds = {}, hasIdle = {}, hasNotIdle = {};
	var globalFlids = [];
	if (this.shouldRender) {
		globalFlids = this._getGlobalFlids();
		for (var i = 0; i < globalFlids.length; i++) {
			var flid = globalFlids[i];
			defaultPrevAvailElemIds[flid] = prevAvailElemIds[flid] = this._getAvailableMarkerId(flid);
			prevIdleElemIds[flid] = this._getIdleMarkerId(flid);
			hasIdle[flid] = hasNotIdle[flid] = false;
		}
	}
	var noResize = false;
	var flidTracking = function (id, flid, isIdle) {
		var itemID = this._getBuddyListItemId(id, flid);
		if (isIdle) {
			prevIdleElemIds[flid] = itemID;
		} else {
			prevAvailElemIds[flid] = itemID;
		}
		hasIdle[flid] = hasIdle[flid] || isIdle;
		hasNotIdle[flid] = hasNotIdle[flid] || !isIdle;
	};
	var flidTrackingFunc = flidTracking.bind(this);
	while (true) {
		if (availableID && wasAvailableList[availableID] && !wasAvailableMultipleLists[availableID]) {
			availableID = availableIDs.shift();
			continue;
		}
		if (availableID && nowAvailableID) {
			if (availableID == nowAvailableID) {
				availableID = availableIDs.shift();
				continue;
			}
			if (compareFunction(availableID, nowAvailableID, this.availableList[availableID].i, nowAvailableList[nowAvailableID].i) < 0) {
				id = availableID;
			} else {
				id = nowAvailableID;
			}
		} else {
			if (availableID) {
				id = availableID;
			} else {
				if (nowAvailableID) {
					id = nowAvailableID;
				} else {
					break;
				}
			}
		}
		if (id == availableID) {
			availableID = availableIDs.shift();
			isIdle = this.availableList[id].i;
			if (this.shouldRender) {
				var flids = this._getUserFlids(id);
				for (var i = 0; i < flids.length; i++) {
					flidTrackingFunc(id, flids[i], isIdle);
				}
			}
		} else {
			nowAvailableID = nowAvailableIDs.shift();
			if (this.shouldRender && this.availableList[id]) {
				var toRemoveFlids = this._getUserFlids(id, this.availableList[id], filterExternalFlids);
				for (var i = 0; i < toRemoveFlids.length; i++) {
					var flid = toRemoveFlids[i];
					var elem = ge(this._getBuddyListItemId(id, flid));
					if (elem) {
						this._removeSortable(id, flid);
						DOM.remove(elem);
					}
				}
			}
			this.availableList[id] = nowAvailableList[id];
			if (this.shouldRender) {
				isIdle = nowAvailableList[id].i;
				var flids = this._getUserFlids(id, null, filterExternalFlids);
				for (var i = 0; i < flids.length; i++) {
					var flid = flids[i];
					var prevElem = isIdle ? ge(prevIdleElemIds[flid]) : ge(prevAvailElemIds[flid]);
					if (!prevElem) {
						prevElem = ge(defaultPrevAvailElemIds[flid]);
					}
					this._expandItem(id, flid, prevElem, isIdle, shouldAnimate, shouldDelayExpand);
					noResize = true;
					flidTrackingFunc(id, flid, isIdle);
				}
			}
		}
		if (this.haveFullList) {
			this.sortedList.push(id);
		}
	}
	if (this.shouldRender) {
		for (var i = 0; i < globalFlids.length; i++) {
			var flid = globalFlids[i];
			var idleMarker = ge(this._getIdleMarkerId(flid));
			if (idleMarker) {
				if (hasIdle[flid] && hasNotIdle[flid]) {
					CSS.removeClass(idleMarker, "hide_idle_marker");
				} else {
					CSS.addClass(idleMarker, "hide_idle_marker");
				}
			}
		}
		var delay = 0;
		if (shouldAnimate) {
			var didExpand = noResize;
			if (didExpand) {
				delay += this.expandAnimDuration;
			}
			if (shouldDelayExpand) {
				delay += this.expandAnimDuration;
				if (didExpand) {
					delay += 500;
				}
			}
		}
		setTimeout(this.resizeTab.bind(this), delay);
		this._resetFlidClasses();
	}
	this._availableListChanged(noResize);
}, _sort:function (ids, availableList) {
	availableList = availableList || this.availableList;
	var compareFunction = this._compareFunction.bind(this, availableList);
	ids.sort(compareFunction);
	return ids;
}, _compareFunction:function (availableList, id1, id2, id1Idle, id2Idle) {
	if (typeof id1Idle == "undefined") {
		id1Idle = availableList[id1].i;
	}
	if (typeof id2Idle == "undefined") {
		id2Idle = availableList[id2].i;
	}
	if (id1Idle ^ id2Idle) {
		return id1Idle ? 1 : -1;
	}
	var id1Name = chatDisplay.userInfos[id1].name.toLowerCase();
	var id2Name = chatDisplay.userInfos[id2].name.toLowerCase();
	return (id1Name < id2Name) ? -1 : 1;
}, _availableListChanged:function (noResize) {
	if (this.haveFullList) {
		this.availableCount = count(this.availableList);
	}
	for (var id in this.availableList) {
		this.availableList[id].i = this.availableList[id].i ? 1 : 0;
	}
	if (this.rendered) {
		presenceCookieManager.store();
	}
	presence.contentChanged(this.contentID);
	if (!noResize) {
		this.resizeTab();
	}
	this._updateCount();
	Arbiter.inform(ChatBuddyList.AVAILABILITY_CHANGED, {sender:this, justCameOnline:this.justCameOnline});
	this.justCameOnline = false;
}, _onUpdaterResponse:function (buddyListResponse, time) {
	if (this.shouldRender && !buddyListResponse.forcedRender) {
		return;
	}
	this.updateTime = time;
	if (!chatOptions.visibility) {
		return;
	}
	if (this.stopUpdates) {
		return;
	}
	var hadFullList = this.haveFullList;
	var flChanged = this._flChanged(buddyListResponse.flMode, buddyListResponse.flData);
	var nowAvailableListEmpty = is_empty(buddyListResponse.nowAvailableList);
	this.numRequestFailures = 0;
	this.errorMode = false;
	this._hideError();
	this.listChanged = buddyListResponse.listChanged;
	this.updateUserInfos(buddyListResponse.userInfos);
	if ((hadFullList && flChanged) || nowAvailableListEmpty) {
	} else {
		this.flMode = buddyListResponse.flMode;
		this.flData = buddyListResponse.flData;
	}
	if (this.shouldRender) {
		this.haveFullList = true;
		if (!this.rendered) {
			this._firstRender();
		}
	} else {
		this.availableCount = buddyListResponse.availableCount;
		this._updateCount();
	}
	if (!hadFullList || buddyListResponse.wasAvailableIDs.length || !nowAvailableListEmpty) {
		for (var id in this.updateOverlay) {
			if (time < this.updateOverlay[id].exp) {
				if (hadFullList || !this.availableList[id]) {
					delete buddyListResponse.nowAvailableList[id];
				} else {
					buddyListResponse.nowAvailableList[id] = this.availableList[id];
				}
				for (var i = 0; i < buddyListResponse.wasAvailableIDs.length; i++) {
					if (id == buddyListResponse.wasAvailableIDs[i]) {
						buddyListResponse.wasAvailableIDs.splice(i, 1);
						break;
					}
				}
			} else {
				delete this.updateOverlay[id];
			}
		}
		if (hadFullList) {
			if (flChanged && !nowAvailableListEmpty) {
				buddyListResponse.nowAvailableList = this._massageNowAvailableList(buddyListResponse.nowAvailableList, buddyListResponse.flMode, buddyListResponse.flData);
			}
			this._updateAvailableListWithDiff(buddyListResponse.nowAvailableList, buddyListResponse.wasAvailableIDs);
			if (flChanged) {
				this._onFlChange(buddyListResponse.flMode, buddyListResponse.flData);
			}
		} else {
			this.availableList = buddyListResponse.nowAvailableList;
			this._availableListChanged(true);
			if (this.shouldRender) {
				this._render();
			}
		}
	} else {
		this._availableListChanged.bind(this).defer();
		if (flChanged && nowAvailableListEmpty) {
			this._onFlChange(buddyListResponse.flMode, buddyListResponse.flData);
		}
	}
}, _onUpdaterError:function (response) {
	this.numRequestFailures++;
	if (this.numRequestFailures > 1) {
		this.updateTime = presence.getTime();
		this.availableCount = 0;
		this._updateCount();
		this._updateAvailableListWithDiff({}, keys(this.availableList));
		this._showLoadError();
	}
}, itemOnClick:function (id, flid) {
	var elem;
	if ((elem = ge(this._getBuddyListItemId(id, flid))) && elem.activeDrag) {
		return;
	}
	presence.pauseSync();
	chatDisplay.focusTab(id);
	if (!this.isSticky()) {
		this.closeTab();
	}
	if (this.typeahead) {
		this.typeahead.resetSearch(true);
	}
	Arbiter.inform(ChatBuddyList.BUDDY_CLICKED, {flid:flid, id:id});
	presence.resumeSync();
}, _renderItem:function (id, flid, isIdle) {
	var userInfo = chatDisplay.userInfos[id];
	var name = userInfo.name;
	var picSrc = userInfo.thumbSrc;
	var nameCapped;
	if (name.length > this.maxNameLen) {
		nameCapped = name.substring(0, this.maxNameLen - 2) + "...";
	} else {
		nameCapped = name;
	}
	var status, anchorTitle = "", statusCapped = "";
	if (status = userInfo.status) {
		anchorTitle = isIdle ? _tx("{Idle} - {name} {status} ({time})", {"name":htmlize(name), "Idle":_tx("Idle"), "status":htmlize(status), "time":userInfo.statusTimeRel}) : _tx("{name} {status} ({time})", {"name":htmlize(name), "status":htmlize(status), "time":userInfo.statusTimeRel});
	} else {
		if (isIdle) {
			anchorTitle = _tx("Idle");
		}
	}
	if (flid) {
		var onclick = sprintf("buddyList.itemOnClick(%d, '%s')", id, flid);
	} else {
		var onclick = sprintf("buddyList.itemOnClick(%d)", id);
	}
	var markupArr = ["<a href=\"#\" class=\"clearfix\" title=\"", anchorTitle, "\" ", "onclick=\"", onclick, ";return false;\">"];
	var fullDisplay = !this.isCompactDisplay;
	var opts = this._getFlOpts(flid);
	fullDisplay &= opts.fullDisplay;
	if (fullDisplay) {
		markupArr = markupArr.concat("<img src=\"", picSrc, "\" width=\"22px\" height=\"22px\" />");
	}
	markupArr = markupArr.concat("<div class=\"friend_status\">", "<strong id=\"", this._getBuddyListItemNameId(id, flid), "\">", htmlize(nameCapped), "</strong>");
	markupArr = markupArr.concat("</div>", "<div class=\"available_dot\"></div>", "</a>");
	return markupArr.join("");
}, _groupAvailableListByFl:function (groupSorted, emptyGroups) {
	if (!this.flMode || !this.flData) {
		return null;
	}
	groupSorted = groupSorted || false;
	emptyGroups = emptyGroups || false;
	var result = {};
	for (var flid in this.flData) {
		result[flid] = [];
	}
	if (emptyGroups) {
		return result;
	}
	var groupId = function (id) {
		var flids = this.availableList[id].fl;
		if (flids) {
			for (var j = 0; j < flids.length; ++j) {
				var flid = flids[j];
				result[flid].push(id);
			}
		}
	};
	var groupIdFunc = groupId.bind(this);
	if (groupSorted) {
		var sortedList = this._getSortedList();
		for (var i = 0; i < sortedList.length; i++) {
			groupIdFunc(sortedList[i]);
		}
	} else {
		for (var id in this.availableList) {
			groupIdFunc(id);
		}
	}
	return result;
}, _listNameInUse:function (name) {
	for (var flid in this.flData) {
		if (this.flData[flid].n == name) {
			return true;
		}
	}
	return false;
}, keyPressNewListInput:function (e) {
	if (event_get_keypress_keycode(e) == KEYS.RETURN) {
		var e = $E(e);
		var list_name = e.getTarget().value;
		if (this._listNameInUse(list_name)) {
			new ErrorDialog().showError(_tx("An error occurred."), _tx("You cannot have two lists with the same name. Please create a unique name for this list."));
			return;
		}
		var data = {"create":list_name};
		this._saveBuddyListSetting(data, function () {
			for (var flid in this.flData) {
				if (this.flData[flid].n == list_name) {
					Vector2.scrollIntoView($(this._getFriendListId(flid)));
					break;
				}
			}
		}.bind(this));
		return e.kill();
	}
}, handleFlInChat:function (is_visible, flid) {
	buddyListDisplay.closeOpenFlyout();
	if (is_visible) {
		this._unHideFriendListFromChat(flid);
	} else {
		this._hideFriendListFromChat(flid);
	}
}, _unHideFriendListFromChat:function (flid) {
	var noLists = this._getFriendListsInChat().length == 0;
	var flids = [flid];
	var data = {"unhide_from_chat":1, "flids":flids};
	this.flData[flid].h = 0;
	this._saveBuddyListSetting(data, function () {
		this._showEmptyListMomentarily(flid);
		Vector2.scrollIntoView($(this._getFriendListId(flid)));
	}.bind(this));
	if (noLists) {
		this._onFlChange(true, this.flData);
	} else {
		this._addFlidsToDOM(flids);
	}
}, _hideFriendListFromChat:function (flid) {
	var lastList = this._getFriendListsInChat().length == 1;
	var flids = [flid];
	var data = {"hide_from_chat":1, "flids":flids};
	this.flData[flid].h = 1;
	this._saveBuddyListSetting(data);
	if (lastList) {
		this._onFlChange(false, this.flData);
	} else {
		this._removeFlidsFromBuddyList(flids);
	}
}, _friendListHandleSwitchThrown:function (flid) {
	var currentlyOnline = this.flData[flid].o;
	if (currentlyOnline) {
		this._goOfflineToLists([flid]);
	} else {
		this._goOnlineToLists([flid]);
	}
}, _friendListHandleSwitchMouseDown:function (flid) {
	var evt = Event.listen(document, "mouseup", function () {
		evt.remove();
		this._friendListHandleSwitchThrown(flid);
	}.bind(this));
}, _friendListHandleMouseOver:function (flid) {
	if (this.reorderingLists) {
		return;
	}
	CSS.addClass($(this._getFriendListId(flid)), "hover");
}, _friendListHandleMouseOut:function (flid) {
	CSS.removeClass($(this._getFriendListId(flid)), "hover");
}, _friendListHandleEditLinckClick:function (flid) {
	if (!this.reorderingLists) {
		Dialog.bootstrap(DialogBootstrapEndpoints.LIST_EDITOR, {list_id:flid});
	}
	return false;
}, _saveBuddyListSetting:function (data, callback) {
	data["user"] = this.user;
	callback = callback || bagofholding;
	new AsyncRequest().setData(data).setURI("/ajax/chat/buddy_list_settings.php").setHandler(this._onBuddyListSettingSave.bind(this, callback)).setFinallyHandler(function () {
		buddyListDisplay.closeOpenFlyout();
	}).send();
}, _goOnlineToLists:function (flids, readOnly) {
	readOnly = readOnly || false;
	var data = {"online_to_list":1, "flids":flids, "read_only":readOnly};
	this._handleFlVisibilityChange(flids, 1);
	this._saveBuddyListSetting(data);
}, _handleFlVisibilityChange:function (flids, online, callback) {
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		var flItem = ge(this._getFriendListId(flid));
		if (!flItem) {
			continue;
		}
		this.flData[flid].o = online;
		if (online) {
			CSS.addClass(flItem, "online");
			CSS.removeClass(flItem, "offline");
			if (flid == this.otherFriendsFlid) {
				this._showEmptyListMomentarily(flid);
			}
		} else {
			CSS.addClass(flItem, "offline");
			CSS.removeClass(flItem, "online");
		}
		var tooltip = DOM.find(flItem, "div.titletip strong");
		DOM.setText(tooltip, this._getFriendListTooltipText(flid));
		callback && callback(flid);
	}
}, _showEmptyListMomentarily:function (flid) {
	this.shownEmptyFlids = this.shownEmptyFlids || {};
	this.shownEmptyFlids[flid] = 1;
	var flItem = ge(this._getFriendListId(flid));
	if (flItem) {
		CSS.addClass(flItem, "show_empty_list");
	}
	(function () {
		delete this.shownEmptyFlids[flid];
		var flItem = ge(this._getFriendListId(flid));
		if (flItem) {
			CSS.removeClass(flItem, "show_empty_list");
		}
	}).bind(this).defer(8000);
}, _goOfflineToLists:function (flids, uiOnly) {
	uiOnly = uiOnly || false;
	var groupedLists = this._groupAvailableListByFl();
	this._handleFlVisibilityChange(flids, 0, function (flid) {
		var idsToRemove = groupedLists[flid];
		this._removeFromBuddyList(idsToRemove, flid);
	}.bind(this));
	if (!uiOnly) {
		var data = {"offline_to_list":1, "flids":flids};
		this._saveBuddyListSetting(data);
	}
}, _removeFlidsFromBuddyList:function (flids, groupedList) {
	groupedList = groupedList || this._groupAvailableListByFl(true);
	if (!groupedList) {
		return;
	}
	var nowAvailList = {};
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		var ids = groupedList[flid];
		if (!ids) {
			continue;
		}
		for (var j = 0; j < ids.length; j++) {
			var id = ids[j];
			var buddyInfo = {};
			buddyInfo["i"] = this.availableList[id].i;
			buddyInfo["fl"] = this.availableList[id].fl.clone();
			if (this.flMode) {
				buddyInfo.fl.remove(flid);
				if (buddyInfo.fl.length == 0) {
					buddyInfo.fl.push(this.otherFriendsFlid);
				}
			} else {
				delete buddyInfo.fl;
			}
			nowAvailList[id] = buddyInfo;
		}
	}
	if (!is_empty(nowAvailList)) {
		this._updateAvailableListWithDiff(nowAvailList, []);
	}
	this._removeFlidsFromDOM(flids);
}, _onBuddyListSettingSave:function (callback, asyncResponse) {
	var payload = asyncResponse.getPayload();
	if (payload) {
		if (payload.availableList) {
			this.updateUserInfos(payload.userInfos);
			var flid;
			if (payload.flids && payload.flids.length == 1) {
				flid = payload.flids[0];
			}
			this._updateAvailableListWithDiff(payload.availableList, [], flid);
		}
		if (payload.flData) {
			var flMode;
			if (typeof payload.flMode != "undefined") {
				flMode = payload.flMode;
			} else {
				flMode = true;
			}
			this._onFlChange(flMode, payload.flData);
			this._resetFlidClasses();
		}
		callback && callback();
	}
}, _flManagerHandler:function (message, data) {
}, _resetFlidClasses:function () {
	if (!this.flMode) {
		return;
	}
	var groupedFl = this._groupAvailableListByFl();
	for (var flid in this.flData) {
		var flItem = ge(this._getFriendListId(flid));
		if (flItem) {
			CSS.setClass(flItem, this._getFriendListItemClasses(flid, groupedFl));
		}
	}
}, _getFriendListItemClasses:function (flid, groupedFl) {
	var flid_online = this.flData[flid].o;
	var flid_hidden = this.flData[flid].h;
	var classes = ["friend_list"];
	if (flid_online) {
		classes.push("online");
	} else {
		classes.push("offline");
	}
	if (!flid_hidden && this.shownEmptyFlids && this.shownEmptyFlids[flid]) {
		classes.push("show_empty_list");
	}
	if (is_empty(groupedFl[flid])) {
		if (this.availableCount != 0 && (this.flData[flid].c == 0 || flid == this.otherFriendsFlid)) {
			classes.push("empty_friend_list");
		} else {
			if (flid_online) {
				classes.push("hide_friend_list");
			}
		}
	}
	if (flid == this.otherFriendsFlid) {
		classes.push("compact_friend_list");
		classes.push("other_friends_list");
	}
	if (this.reorderingLists && (flid == this.otherFriendsFlid || flid == this.botsFlid)) {
		classes.push("suppress");
	}
	return classes.join(" ");
}, _renderFriendListHeader:function (flid) {
	var fl_name = this.flData[flid].n;
	var online = this.flData[flid].o;
	var edit_link = "";
	var sacred = typeof this.flData[flid].s != "undefined";
	if (!sacred && flid != this.otherFriendsFlid) {
		edit_link = _tx("edit");
	}
	var markupArr = ["<div class=\"friendlist_status\">", "<span class=\"title\"><a href=\"#\">", htmlize(fl_name), "</a></span>", "<span class=\"edit_link\">", "<a href=\"#\">", edit_link, "</a>", "</span>", "</div>"];
	if (!sacred) {
		markupArr.push("<div class=\"online_status_container\"><a class=\"online_status\" ", ">", "<div class=\"titletip\"><strong>", this._getFriendListTooltipText(flid), "</strong></div>", "</a>", "</div>");
	}
	return markupArr.join("");
}, _getFriendListTooltipText:function (flid) {
	return this.flData[flid].o ? _tx("Go Offline") : _tx("Go Online");
}, registerExternalFriendList:function (opts) {
	if (!this.rendered) {
		this._firstRender();
	}
	var flid = "xfl_" + this.externalFlids.length;
	this.externalFlids.push(flid);
	this.flOpts[flid] = opts;
	return flid;
}, _renderFriendListContent:function (flid, ids) {
	var markupArr;
	var haveFlid = this.flMode && flid;
	if (haveFlid) {
		markupArr = ["<ul id=\"", this._getFriendListContainerId(flid), "\"", "class=\"friend_list_container\">"];
	} else {
		markupArr = [];
	}
	markupArr.push("<li id=\"", this._getAvailableMarkerId(flid), "\" class=\"suppress\"></li>");
	var idleArr = [];
	var hasIdle = false, hasNotIdle = false;
	for (var j = 0; j < ids.length; j++) {
		var id = ids[j];
		var idle = this.availableList[id].i;
		var itemMarkupArr = ["<li id=\"", this._getBuddyListItemId(id, flid), "\"", (idle ? " class=\"idle\"" : ""), ">", this._renderItem(id, flid, idle), "</li>"];
		if (idle) {
			hasIdle = true;
			idleArr = idleArr.concat(itemMarkupArr);
		} else {
			hasNotIdle = true;
			markupArr = markupArr.concat(itemMarkupArr);
		}
	}
	var idleMarkerClass = (hasIdle && hasNotIdle) ? "" : " hide_idle_marker";
	markupArr.push("<li id=\"", this._getIdleMarkerId(flid), "\" class=\"subheader", idleMarkerClass, "\"></li>");
	markupArr = markupArr.concat(idleArr);
	if (haveFlid) {
		markupArr.push("</ul>");
	}
	return markupArr.join("");
}, _addFriendListListeners:function (flids) {
	if (!this.flMode) {
		return;
	}
	flids = flids || this._getRenderedFriendLists();
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		if (typeof this.flData[flid].s != "undefined") {
			continue;
		}
		var flItem = $(this._getFriendListId(flid));
		Event.listen(flItem, "mouseover", this._friendListHandleMouseOver.bind(this, flid));
		Event.listen(flItem, "mouseout", this._friendListHandleMouseOut.bind(this, flid));
		var switch_link = DOM.find(flItem, "a.online_status");
		Event.listen(switch_link, "mousedown", this._friendListHandleSwitchMouseDown.bind(this, flid));
		if (flid != this.otherFriendsFlid) {
			var edit_link_area = DOM.find(flItem, "div.friendlist_status");
			Event.listen(edit_link_area, "click", this._friendListHandleEditLinckClick.bind(this, flid));
		}
	}
}, _renderBuddyContent:function () {
	var emptyItemClass = (this.availableCount ? "hide_empty_item" : "");
	var markupArr = ["<div id=\"buddy_list_all\" class=\"subgroup\">", this.renderEmptySearch(), "<ul id=\"buddy_list_parent\" class=\"list_select\">", "<li id=\"", this._getBuddyListEmptyItemId(), "\" class=\"info_text ", emptyItemClass, "\">", _tx("No one is available to chat."), "</li>"];
	var flids;
	var groupedLists = {};
	if (this.flMode) {
		flids = keys(this.flData);
		groupedLists = this._groupAvailableListByFl(true);
	} else {
		flids = [null];
	}
	for (var i = 0; i < flids.length; ++i) {
		var flid = flids[i];
		var ids = [];
		if (this.flMode && flid) {
			if (this.flData[flid].h) {
				continue;
			}
			markupArr.push("<li id=\"", this._getFriendListId(flid), "\"", "class=\"", this._getFriendListItemClasses(flid, groupedLists), "\">", this._renderFriendListHeader(flid));
			ids = groupedLists[flid];
		} else {
			ids = this._getSortedList();
		}
		markupArr.push(this._renderFriendListContent(flid, ids));
		if (this.flMode && flid) {
			markupArr.push("</li>");
		}
	}
	markupArr.concat(["</ul>", "</div>"]);
	return markupArr.join("");
}, renderEmptySearch:function (flid) {
	var html = "<div id=\"" + this._getEmptySearchId(flid) + "\" class=\"info_text\" style=\"display:none\">" + _tx("Could not find that friend online.") + "</div>";
	return html;
}, _render:function () {
	this._getSortedList();
	CSS.conditionClass(this.contentDiv, "compact", this.isCompactDisplay);
	var content = this._renderBuddyContent();
	if (this.rendered) {
		CSS.addClass(this.contentDiv, "hidden");
	}
	this.contentDiv.innerHTML = content;
	presence.contentChanged(this.contentID);
	if (this.rendered) {
		CSS.addClass(this.wrapperDiv, "presence_menu_offscreen");
		this._hideError();
		CSS.removeClass(this.contentDiv, "hidden");
		this.resizeTab();
		CSS.removeClass(this.wrapperDiv, "presence_menu_offscreen");
		this._initDragging();
		this._addFriendListListeners();
	}
	if (this.errorMode) {
		this._showLoadError();
	}
	if (this.shouldShowLoading) {
		this._showLoading();
		this.shouldShowLoading = false;
	}
}, _firstRender:function () {
	this._render();
	this.rendered = true;
	this.loadTypeahead();
}, updateItemDisplay:function (id) {
	var buddyInfo = this.availableList[id];
	if (!buddyInfo) {
		return;
	}
	var userFlids = this._getUserFlids(id);
	for (var i = 0; i < userFlids.length; i++) {
		var flid = userFlids[i];
		var item = ge(this._getBuddyListItemId(id, flid));
		if (!item) {
			return;
		}
		item.innerHTML = this._renderItem(id, flid, buddyInfo.i);
	}
}, _showLoadError:function () {
	this._showError(_tx("Could not load available friends."));
}, _showLoading:function () {
	this._showError(_tx("Loading..."));
}, _hideError:function () {
	this.showingError = false;
	CSS.removeClass(this.wrapperDiv, "error");
}, _showError:function (error) {
	this.showingError = true;
	set_inner_html(this.buddyListError, error);
	CSS.addClass(this.wrapperDiv, "error");
}, isSticky:function () {
	return chatOptions.getSetting("sticky_buddylist");
}, enterReorderingFlMode:function () {
	if (this.reorderingLists) {
		return;
	}
	this.reorderingLists = true;
	CSS.addClass(this.wrapperDiv, "reorder_fl");
	var allFlids = this._getRenderedFriendLists();
	this.flSortableGroup = new SortableGroup();
	for (var i = 0; i < allFlids.length; i++) {
		var flid = allFlids[i];
		if (flid == this.otherFriendsFlid || flid == this.botsFlid) {
			CSS.addClass(this._getFriendListId(flid), "suppress");
		} else {
			this._addFlSortable(flid);
		}
	}
	var reorder_alert = $N("div", {id:"reorder_fl_alert"}, [$N("span", {className:"helper_text"}, _tx("Drag lists to re-order.")), $N("input", {type:"button", className:"inputbutton", value:_tx("Done Re-Ordering"), onclick:this.exitReorderingFlMode.bind(this)})]);
	DOM.insertBefore(reorder_alert, this.contentDiv);
	this.freezeTabSize(false);
}, exitReorderingFlMode:function () {
	if (!this.reorderingLists) {
		return;
	}
	this._reorderFlids();
	DOM.remove($("reorder_fl_alert"));
	CSS.removeClass(this.wrapperDiv, "reorder_fl");
	var allFlids = this._getRenderedFriendLists();
	for (var i = 0; i < allFlids.length; i++) {
		var flid = allFlids[i];
		if (flid == this.otherFriendsFlid || flid == this.botsFlid) {
			CSS.removeClass(this._getFriendListId(flid), "suppress");
		} else {
			this._removeFlSortable(flid);
		}
	}
	this.reorderingLists = false;
	this.unfreezeTabSize.bind(this).defer(50);
	this.flSortableGroup.destroy();
	this.flSortableGroup = null;
}, _addFlSortable:function (flid) {
	if (this.flSortableGroup != null) {
		this.flSortableGroup.addSortable(flid, $(this._getFriendListId(flid)));
		animation($(this._getFriendListContainerId(flid))).to("height", "0px").to("opacity", 0).from(1).blind().hide().ease(animation.ease.end).duration(300).go();
	}
}, _removeFlSortable:function (flid) {
	if (this.flSortableGroup != null) {
		this.flSortableGroup.removeSortable(flid);
		var container;
		if (container = ge(this._getFriendListContainerId(flid))) {
			animation(container).to("height", "auto").from("0px").to("opacity", 1).from(0).blind().show().ease(animation.ease.end).duration(300).go();
		}
	}
}, _reorderFlids:function () {
	var data = {"reorder":1, "flids":this.flSortableGroup.getOrder()};
	this._saveBuddyListSetting(data);
}, _getDragKey:function (id, flid) {
	return id + "_" + flid;
}, _initDragging:function () {
	if (!this.flMode) {
		return;
	}
	var groupedLists = this._groupAvailableListByFl();
	this.sortables = {};
	var flids = this._getRenderedFriendLists();
	for (var i = 0; i < flids.length; i++) {
		var flid = flids[i];
		var ids = groupedLists[flid];
		this._initFlidSortable(flid, ids);
	}
}, _initFlidSortable:function (flid, ids) {
	if (!flid || !this.flMode) {
		return;
	}
	if (this.flData[flid].s) {
		return;
	}
	var firstFlid = head(this.sortables);
	this.sortables[flid] = new SortableGroup();
	if (firstFlid) {
		firstFlid.link(this.sortables[flid]);
	}
	var emptyMessage = $N("li", {id:this._getEmptyListDropZoneId(flid), className:"list_drop_zone"}, $N("span", {className:"list_drop_zone_inner"}, _tx("Drag a friend here to add")));
	var root = $(this._getFriendListContainerId(flid));
	this.sortables[flid].addEmptyMessage(emptyMessage, root).setBoundingBox(this._getBoundingBox()).setDragOverCallback(this._dragOverHandler.bind(this)).setDropCallback(this._dropHandler.bind(this));
	for (var j = 0; j < ids.length; j++) {
		this._addSortable(ids[j], flid);
	}
}, _getBoundingBox:function () {
	return Rect.newFromVectors(new Vector2(0, 0), Vector2.getElementDimensions(this.contentDiv));
}, _destroyFlidSortable:function (flid) {
	if (!flid || !this.flMode) {
		return;
	}
	if (this.sortables && this.sortables[flid]) {
		this.sortables[flid].destroy();
		delete this.sortables[flid];
	}
}, _addSortable:function (id, flid) {
	if (!flid || !this.flMode || !this.flData[flid]) {
		return;
	}
	if (this.flData[flid].s) {
		return;
	}
	if (!this.sortables[flid]) {
		return;
	}
	var key = this._getDragKey(id, flid);
	if (this.sortables[flid].keyExists(key)) {
		return;
	}
	this.sortables[flid].addSortable(key, ge(this._getBuddyListItemId(id, flid)));
}, _removeSortable:function (id, flid, otherFlid) {
	if (!flid || !this.flMode) {
		return;
	}
	if (this.sortables[flid]) {
		this.sortables[flid].removeSortable(this._getDragKey(id, otherFlid || flid));
	}
}, _dragOverHandler:function (draggable, droppable) {
	if (CSS.hasClass(droppable, "list_drop_zone")) {
		var flid = this._extractFlid(droppable.id);
		var parent = $(this._getFriendListId(flid));
		CSS.addClass(parent, "drag_over");
	}
}, _dropHandler:function (key) {
	var temp = key.split("_");
	if (temp.length != 2) {
		return;
	}
	var id = temp[0];
	var oldFlid = temp[1];
	var draggedItem = $(this._getBuddyListItemId(id, oldFlid));
	if (!draggedItem) {
		return;
	}
	var newFlid = this._extractFlid(draggedItem.parentNode.id);
	if (newFlid == oldFlid) {
		this._updateUIAfterDragging(id, oldFlid, oldFlid, draggedItem);
	} else {
		if (this.flData[oldFlid].s || this.flData[newFlid].s) {
			this._updateUIAfterDragging(id, oldFlid, oldFlid, draggedItem);
			return;
		}
		var currentFlids = this.availableList[id].fl;
		var movingList = false;
		var removingList = false;
		var saveData = false;
		if (newFlid == this.otherFriendsFlid) {
			removingList = true;
			if (currentFlids.length == 1) {
				this.availableList[id].fl = [this.otherFriendsFlid];
			} else {
				this.availableList[id].fl.remove(oldFlid);
				saveData = true;
				DOM.remove(draggedItem);
				Vector2.scrollIntoView(this.getBuddyItem(id));
			}
		} else {
			if (currentFlids.length == 1) {
				this.availableList[id].fl = [newFlid];
				movingList = oldFlid != this.otherFriendsFlid;
			} else {
				movingList = true;
				this.availableList[id].fl.push(newFlid);
				this.availableList[id].fl.remove(oldFlid);
			}
		}
		if (saveData || this._updateUIAfterDragging(id, oldFlid, newFlid, draggedItem)) {
			var data;
			if (removingList) {
				data = {"remove_fl":true, "old_flid":oldFlid, "drag_uid":id};
			} else {
				if (movingList) {
					data = {"move_fl":true, "new_flid":newFlid, "old_flid":oldFlid, "drag_uid":id};
				} else {
					data = {"add_fl":1, "new_flid":newFlid, "drag_uid":id};
				}
			}
			this._saveBuddyListSetting(data);
		}
	}
	this._resetFlidClasses();
}, _updateUIAfterDragging:function (id, oldFlid, newFlid, draggedItem) {
	var groupedLists = this._groupAvailableListByFl(true);
	var sortedList = groupedLists[newFlid];
	var index = sortedList.indexOf(id);
	var prevElem;
	if (index == -1) {
		return false;
	} else {
		if (index == 0) {
			prevElem = $(this._getAvailableMarkerId(newFlid));
		} else {
			prevElem = $(this._getBuddyListItemId(sortedList[index - 1], newFlid));
		}
	}
	(function () {
		var shouldAnimate, showHighlight = false;
		if (sortedList.length != 1) {
			shouldAnimate = showHight = true;
		}
		var newItem = this._expandItem(id, newFlid, prevElem, this.availableList[id].i, shouldAnimate, false, showHighlight);
		if (oldFlid != newFlid) {
			DOM.remove(draggedItem);
			this._removeSortable(id, newFlid, oldFlid);
		}
		Vector2.scrollIntoView(newItem);
	}).bind(this).defer(500);
	return true;
}, _getGlobalFlids:function (filterExternalFlids) {
	var flids = this.flMode && this.flData ? keys(this.flData) : [null];
	return filterExternalFlids ? flids : flids.concat(this.externalFlids);
}, _getUserFlids:function (id, buddyInfo, filterExternalFlids) {
	buddyInfo = buddyInfo || this.availableList[id];
	var flids = buddyInfo.fl ? buddyInfo.fl : [null];
	if (!filterExternalFlids) {
		if (!buddyInfo.allFlids) {
			buddyInfo.allFlids = this._addExternalFlids(id, flids);
		}
		flids = buddyInfo.allFlids;
	}
	return flids;
}, _addExternalFlids:function (id, flids) {
	flids = flids.concat();
	for (var i = 0; i < this.externalFlids.length; i++) {
		var flid = this.externalFlids[i];
		var opts = this._getFlOpts(flid);
		if (!opts.excludeIds[id]) {
			flids.push(flid);
		}
	}
	return flids;
}, _getFlOpts:function (flid) {
	return this.flOpts[flid] || ChatBuddyList.DEFAULT_OPTS;
}, _getAvailableMarkerId:function (flid) {
	return this._encodeFlid("buddy_list_avail_marker", flid);
}, _getIdleMarkerId:function (flid) {
	return this._encodeFlid("buddy_list_idle_marker", flid);
}, _getEmptyListDropZoneId:function (flid) {
	return this._encodeFlid("buddy_list_drop_zone", flid);
}, _getBuddyListItemId:function (id, flid) {
	return this._encodeFlid("buddy_list_item_" + id, flid);
}, _getBuddyListItemNameId:function (id, flid) {
	return this._encodeFlid("buddy_list_item_name_" + id, flid);
}, _getBuddyListWasItemId:function (id, flid) {
	return this._encodeFlid("buddy_list_was_item_" + id, flid);
}, _getEmptySearchId:function (flid) {
	return this._encodeFlid("buddy_list_empty_search", flid);
}, _getBuddyListEmptyItemId:function () {
	return "buddy_list_empty_item";
}, _encodeFlid:function (elemId, flid) {
	return flid ? (flid + "_" + elemId) : elemId;
}, _getFriendListId:function (flid) {
	return this._encodeFlid("friend_list_item", flid);
}, _extractFlid:function (id) {
	return id.split("_").shift();
}, _getFriendListContainerId:function (flid) {
	return this._encodeFlid("friend_list_container", flid);
}, debugPrintUpdateOverlay:function () {
	Util.log("buddyList.updateOverlay =");
	var uo = this.updateOverlay;
	for (var id in uo) {
		Util.log(id + ": st = " + uo[id].ol + ", expires in = " + (uo[id].exp - presence.getTime()));
	}
}};
function ChatBuddyListDisplay(buddy_list_panel_id) {
	this.openFlyout = null;
	this.openControl = null;
	this.panelID = buddy_list_panel_id;
	if (presence.inPopoutWindow) {
		this._init();
	} else {
		this.arbiterInit = Arbiter.subscribe(Presence.TAB_OPENED, this._onTabOpen.bind(this));
	}
}
ChatBuddyListDisplay.prototype = {_onTabOpen:function (type, data) {
	var tab = data.tabID;
	if (tab && tab == "buddy_list_tab") {
		Arbiter.unsubscribe(this.arbiterInit);
		this._init();
	}
}, _init:function () {
	this.buddyListPanel = $(this.panelID, true);
	var lists_callback = this._clickControlPanel.bind(this, "buddy_list_panel_lists_control", "buddy_list_panel_lists_flyout", this._getListsFlyoutContent.bind(this));
	Event.listen(DOM.find(this.buddyListPanel, "#buddy_list_panel_lists_control a"), "click", lists_callback);
	var settings_callback = this._clickControlPanel.bind(this, "buddy_list_panel_settings_control", "buddy_list_panel_settings_flyout", this._getChatSettingsNodes.bind(this));
	Event.listen(DOM.find(this.buddyListPanel, "#buddy_list_panel_settings_control a"), "click", settings_callback);
}, _clickVisibilityToggle:function () {
	chatOptions.toggleVisibility();
	this.closeOpenFlyout();
}, _clickReorderLists:function () {
	buddyList.enterReorderingFlMode();
	this.closeOpenFlyout();
}, _clickControlPanel:function (controlID, flyoutID, markupFunc) {
	if (this.openFlyout) {
		if (this.openFlyout == flyoutID) {
			this.closeOpenFlyout();
		} else {
			this.closeOpenFlyout();
			this._openFlyout(controlID, flyoutID, markupFunc());
		}
	} else {
		this._openFlyout(controlID, flyoutID, markupFunc());
	}
	return false;
}, _openFlyout:function (controlID, flyoutID, content) {
	DOM.setContent($(flyoutID), content);
	CSS.removeClass(flyoutID, "hidden_elem");
	CSS.addClass(controlID, "flyout_open");
	if (!presence.poppedOut) {
		var flyoutHeight = Vector2.getElementDimensions($(flyoutID)).y;
		var contentWrapperHeight = Vector2.getElementDimensions(buddyList.getContentWrapper()).y;
		if (flyoutHeight > contentWrapperHeight) {
			CSS.addClass(flyoutID, "flyout_reversed");
		}
	}
	this.openFlyout = flyoutID;
	this.openControl = controlID;
}, isFlyoutOpen:function () {
	return this.openFlyout;
}, closeOpenFlyout:function () {
	if (!this.openFlyout) {
		return;
	}
	CSS.addClass(this.openFlyout, "hidden_elem");
	CSS.removeClass(this.openFlyout, "flyout_reversed");
	CSS.removeClass(this.openControl, "flyout_open");
	this.openFlyout = null;
	this.openControl = null;
}, _getListsFlyoutContent:function () {
	var new_list_input = $N("input", {className:"inputtext", type:"text"});
	new_list_input.listen("keypress", buddyList.keyPressNewListInput.bind(buddyList));
	new TextInputControl(new_list_input).setPlaceholderText(_tx("Type a list name"));
	var new_list = $N("div", {className:"new_list"}, [$N("span", {}, _tx("Create a new list:")), new_list_input]);
	var instructions = $N("div", {className:"text"}, _tx("Display these lists in Chat:"));
	var flData = buddyList.getFriendLists();
	var checklist = new UISelectList();
	checklist.setCallback(buddyList.handleFlInChat.bind(buddyList));
	for (var flid in flData) {
		checklist.addItem(flData[flid].n, !flData[flid].h, flid);
	}
	return [instructions, checklist.getElement(), new_list];
}, _renderListSettingToggle:function (flid, checked, fl_name) {
	return this._renderToggle("list_online_" + flid, checked, fl_name, "list_online_checkbox_" + flid, function (checkbox, evt) {
		buddyList.handleFlInChat(flid, checkbox);
	});
}, _renderChatSettingToggle:function (name, value, label) {
	return this._renderToggle("chat_setting_" + name, value, label, "chat_setting_checkbox_" + name, function (checkbox, evt) {
		this.sendSettingChange(name, checkbox.checked);
	}.bind(this));
}, _renderToggle:function (div_id, checked, label, checkbox_id, onclick) {
	var checkbox = $N("input", {type:"checkbox", id:checkbox_id, name:checkbox_id});
	checkbox.checked = checked;
	checkbox.defaultChecked = checked;
	checkbox.listen("click", onclick.bind(this, checkbox));
	var labelElem = $N("label", {}, label);
	labelElem.setAttribute("for", checkbox_id);
	return $N("div", {className:"chat_setting clearfix", id:div_id}, [$N("div", {className:"input_box"}, [$N("span", {className:"show_loading"}, $N("img", {src:"/images/loaders/indicator_blue_small.gif"})), $N("span", {className:"hide_loading"}, checkbox)]), labelElem]);
}, _getChatSettingsNodes:function () {
	var nodes = [];
	if (this.buddyListPanel) {
		var offline_button = $N("a", {className:"go_offline_control"}, [$N("div", {className:"menu_icon"}), $N("span", {}, _tx("Go Offline"))]);
		offline_button.listen("click", this._clickVisibilityToggle.bind(this));
		var options_actions = $N("div", {className:"options_actions"}, offline_button);
		if (buddyList._getFriendListsInChat().length > 1) {
			var reorder_button = $N("a", {className:"list_reorder_control"}, [$N("div", {className:"menu_icon"}), $N("span", {}, _tx("Re-order Lists"))]);
			reorder_button.listen("click", this._clickReorderLists.bind(this));
			options_actions.appendChild(reorder_button);
		}
		var popout_button = $N("a", {className:"list_popout_control"}, [$N("div", {className:"menu_icon"}), $N("span", {}, (presence.poppedOut ? _tx("Pop in Chat") : _tx("Pop out Chat")))]);
		popout_button.listen("click", presence.popout.bind(presence));
		options_actions.appendChild(popout_button);
		nodes.push(options_actions);
		nodes.push($N("hr", {className:"menu_divider"}));
	}
	var list = [{name:"minifeed", label:_tx("Show {Feed} stories in {Chat}", {"Feed":_tx("Feed"), "Chat":_tx("Chat")})}, {name:"sound", label:_tx("Play Sound for New Messages")}, {name:"sticky_buddylist", label:_tx("Keep Online Friends Window Open")}, {name:"compact_buddylist", label:_tx("Show Only Names in Online Friends")}];
	for (var i = 0; i < list.length; i++) {
		nodes.push(this._renderChatSettingToggle(list[i].name, chatOptions.getSetting(list[i].name), list[i].label));
	}
	return nodes;
}, _onSettingChangeResponse:function (name, value, response) {
	chatOptions.setSetting(name, value);
	CSS.removeClass($("chat_setting_" + name), "chat_setting_loading");
	presence.doSync();
}, _onSettingChangeError:function (name, response) {
	presence.showAsyncError(response, _tx("Couldn't change that setting"));
	CSS.removeClass($("chat_setting_" + name), "chat_setting_loading");
}, sendSettingChange:function (name, value) {
	CSS.addClass($("chat_setting_" + name), "chat_setting_loading");
	var data = {};
	data[name] = value;
	new AsyncRequest().setHandler(this._onSettingChangeResponse.bind(this, name, value)).setErrorHandler(this._onSettingChangeError.bind(this, name)).setTransportErrorHandler(this._onSettingChangeError.bind(this, name)).setData(data).setURI(chatDisplay.settingsURL).send();
}};
function ChatOptions(visibility, settings) {
	this.visibility = visibility;
	this.settings = settings;
	this._init();
}
copy_properties(ChatOptions, {VISIBILITY_CHANGED:"chat/visibility-changed"});
ChatOptions.prototype = {_init:function () {
	presence.registerStateStorer(this._storeState.bind(this));
	presence.registerStateLoader(this._loadState.bind(this));
}, _storeState:function (presenceState) {
	presenceState.vis = this.visibility;
	presenceState.smf = this.getSetting("minifeed");
	presenceState.bls = this.getSetting("sticky_buddylist");
	presenceState.blc = this.getSetting("compact_buddylist");
	presenceState.snd = this.getSetting("sound");
	return presenceState;
}, _loadState:function (presenceState) {
	if (presenceState.vis != this.visibility) {
		this.setVisibility(presenceState.vis);
	}
	this.setSetting("minifeed", presenceState.smf);
	this.setSetting("sticky_buddylist", presenceState.bls);
	this.setSetting("compact_buddylist", presenceState.blc);
	this.setSetting("sound", presenceState.snd);
}, setVisibility:function (visibility) {
	if (visibility == this.visibility) {
		return;
	}
	this.visibility = visibility;
	if (visibility) {
		channelManager.isActionRequest = true;
		channelManager.rebuild(ChannelRebuildReasons.UIRestart);
	} else {
		if (!chatDisplay.gatedFeatures["invisible_channel"]) {
			channelManager.setReady(false);
		}
	}
	Arbiter.inform(ChatOptions.VISIBILITY_CHANGED, {sender:this});
}, _onVisibilityResponse:function (newVisibility, response) {
	presence.pauseSync();
	this.setVisibility(newVisibility);
	if (!presence.inPopoutWindow && !newVisibility) {
		chatDisplay.unfocus();
	}
	presence.resumeSync();
	if (presence.poppedOut) {
		presence.popout();
	}
}, _onVisibilityError:function (response) {
	var chat = _tx("Chat");
	presence.showAsyncError(response, _tx("Couldn't set {Chat} availability", {"Chat":chat}));
}, toggleVisibility:function () {
	this.sendVisibility(!this.visibility);
}, sendVisibility:function (visibility) {
	if (this.visibility == visibility) {
		return;
	}
	this.visibilityAsync = new AsyncRequest().setHandler(this._onVisibilityResponse.bind(this, visibility)).setErrorHandler(this._onVisibilityError.bind(this)).setTransportErrorHandler(this._onVisibilityError.bind(this)).setData({"visibility":visibility}).setURI(chatDisplay.settingsURL).send();
}, getSetting:function (name) {
	return this.settings[name];
}, setSetting:function (name, value) {
	if (this.getSetting(name) == value) {
		return;
	}
	if (name == "minifeed") {
		chatDisplay.reloadTabs();
	}
	if (name == "compact_buddylist") {
		buddyList.setCompactDisplay(value);
	}
	this.settings[name] = value;
}};
function ChatTabSlider() {
	this.handleWidth = 141;
	this.animationTime = 210;
	this._init();
}
ChatTabSlider.prototype = {_init:function () {
	this.org_s = 0;
	this.numToShow = 0;
	this.numShift = 1;
	this.shiftByNumTabs = false;
	this.timer = null;
	this.skipAnimation = false;
	this.chatWidth = null;
	this.tabPos = {};
	this.chat = ge("chat");
	this.chatTabBar = ge("chat_tab_bar");
	this.nextTab = ge("chat_next_tab");
	this.prevTab = ge("chat_previous_tab");
	this.nextCounter = ge("next_count");
	this.prevCounter = ge("prev_count");
	this.numNext = 0;
	this.numPrev = 0;
	this.prevTabs = {};
	this.nextTabs = {};
	this.numMissedNextCounter = ge("next_num_missed");
	this.numMissedPrevCounter = ge("prev_num_missed");
	presence.registerStateLoader(this._load.bind(this));
	presence.registerStateStorer(this._store.bind(this));
	Arbiter.subscribe(Presence.WINDOW_RESIZED, this._resize.bind(this, false));
}, load:function () {
	this._load(presence.state);
	this._resize(true);
}, _load:function (presenceState) {
	var s = 0;
	if (presenceState) {
		s = (presenceState.s ? presenceState.s : s);
	}
	this._setPos(s);
}, _store:function (presenceState) {
	presenceState.s = this._s;
	return presenceState;
}, _calculate:function (onload) {
	this._setMaxWidth();
	if (onload) {
		this.maxWidth -= 16;
	}
	if (presence.poppedOut) {
		this.numToShow = chatDisplay.numTabs;
	} else {
		this.numToShow = parseInt(this.maxWidth / this.handleWidth);
		this.numToShow = this.numToShow > 0 ? this.numToShow : 1;
	}
	if (this.shiftByNumTabs) {
		this.numShift = this.numToShow;
	}
	if (this._s != null) {
		this._setPos(this._s);
	}
}, _setMaxWidth:function () {
	var w = DOMScroll.getScrollRoot().offsetWidth;
	if (ChatTabSlider.presenceWidthTest) {
		var w = $("presence_ui").offsetWidth;
	}
	var divs = ["buddy_list_tab", "status_control_tab", "presence_notifications_tab", "presence_applications_tab", "icon_garden", "bookmarkable_app"];
	for (var i = 0; i < divs.length; i++) {
		w -= (ge(divs[i]) && $(divs[i]).clientWidth != undefined) ? ge(divs[i]).clientWidth : 0;
	}
	this.maxWidth = (presence.poppedOut ? w - 254 : w - 138);
}, _setPos:function (val) {
	if (val < 0) {
		val = 0;
	}
	this._s = val;
	this._e = this._s + this.numToShow;
}, _doSync:function () {
	var changed = (this.org_s != this._s);
	this.org_s = 0;
	if (changed) {
		presence.doSync();
	}
}, _build:function () {
	if (presence.poppedOut) {
		return;
	}
	var all = (this.numToShow >= chatDisplay.numTabs) ? true : false;
	this.setVisibleTabs(all);
	if (all) {
		this.resetCounters();
	} else {
		this.updateCounters();
	}
	this.updateMissedCount();
}, _resize:function (onload) {
	this.org_s = this._s;
	this._calculate(onload);
	this._build();
	this._doSync();
	if (chatDisplay.lastFocused != null) {
		this.gotoTab(chatDisplay.lastFocused);
	}
}, addTab:function (id) {
	this._build();
}, gotoTab:function (id) {
	if (this.tabPos[id] != 0 && !this.tabPos[id]) {
		return;
	}
	var n = parseInt(this.tabPos[id]);
	if (!this._inRange(n)) {
		var p = (n - this.numToShow) + 1;
		this._setPos(p);
		this._build();
	}
}, close:function (id) {
	if (this.tabPos[id] != 0 && !this.tabPos[id]) {
		return;
	}
	delete this.tabPos[id];
	this._setPos(((this.numPrev > 0 || this.numNext > 0) && this._s > 0) ? this._s - 1 : 0);
	this._calculate();
	this._build();
}, setVisibleTabs:function (all) {
	var c = 0;
	for (var id in chatDisplay.tabs) {
		this.tabPos[id] = c;
		if (this._inRange(c, id) || all == true) {
			chatDisplay.tabs[id].show();
		} else {
			chatDisplay.tabs[id].hide();
		}
		c++;
	}
}, _inRange:function (n, id) {
	var s, e = false;
	if (n >= this._s) {
		s = true;
		delete this.prevTabs[id];
	} else {
		this.prevTabs[id] = id;
	}
	if (n < this._e) {
		e = true;
		delete this.nextTabs[id];
	} else {
		this.nextTabs[id] = id;
	}
	return (s && e);
}, updateMissedCount:function () {
	var prev = 0;
	var next = 0;
	for (var id in this.prevTabs) {
		prev += chatDisplay.tabs[id] ? chatDisplay.tabs[id].numMissed : 0;
	}
	this.numMissedPrevCounter.innerHTML = prev;
	this.numMissedPrevCounter.style.display = prev > 0 ? "block" : "none";
	for (var id in this.nextTabs) {
		next += chatDisplay.tabs[id] ? chatDisplay.tabs[id].numMissed : 0;
	}
	this.numMissedNextCounter.innerHTML = next;
	this.numMissedNextCounter.style.display = next > 0 ? "block" : "none";
}, updateCounters:function () {
	this.numNext = chatDisplay.numTabs - this._e;
	this.numPrev = this._s;
	if (this.numNext <= 0) {
		this.numNext = 0;
		CSS.addClass(this.nextTab, "disabled");
	} else {
		CSS.removeClass(this.nextTab, "disabled");
	}
	if (this.numPrev <= 0) {
		this.numPrev = 0;
		CSS.addClass(this.prevTab, "disabled");
	} else {
		CSS.removeClass(this.prevTab, "disabled");
	}
	if (this.numPrev > 0 || this.numNext > 0) {
		show("chat_next_tab");
		show("chat_previous_tab");
	} else {
		hide("chat_next_tab");
		hide("chat_previous_tab");
	}
	this.nextCounter.innerHTML = this.numNext;
	this.prevCounter.innerHTML = this.numPrev;
}, resetCounters:function () {
	this._setPos(0);
	this.updateCounters();
}, shift:function (num) {
	this.org_s = this._s;
	chatDisplay.unfocusNoSync();
	this._shift.bind(this, num).defer();
}, _shift:function (num) {
	this._setPos(this._s < 0 ? 0 : this._s + num);
	this._slide(num);
	if (this.timer || this.skipAnimation) {
		this._slideReset();
		this.skipAnimation = true;
		var t = setTimeout(function () {
			this.skipAnimation = false;
		}.bind(this), 500);
	} else {
		this.timer = setTimeout(function () {
			this._slideReset();
		}.bind(this), this.animationTime);
	}
}, _slide:function (num) {
	this._slideSetup(false);
	this.setVisibleTabs(true);
	this.slideInc = (num * (this.handleWidth));
	this.leftPos = -(num) * (this.numNext * (this.slideInc));
	this.chatTabBar.style.left = this.leftPos + "px";
	animation(this.chatTabBar).by("left", this.slideInc).duration(this.animationTime - 10).go();
}, _slideSetup:function (reset) {
	this.chat.style.position = reset ? "" : "relative";
	this.chat.style.overflow = reset ? "visible" : "hidden";
	if (!this.chatWidth) {
		this.chatWidth = this.chatTabBar.clientWidth;
	}
	if (reset) {
		this.chatWidth = null;
	}
	this.chat.style.width = reset ? "" : this.chatWidth + "px";
	this.chatTabBar.style.width = reset ? "" : chatDisplay.numTabs * this.handleWidth + "px";
	this.chatTabBar.style.position = reset ? "" : "absolute";
}, _slideReset:function () {
	clearTimeout(this.timer);
	this.timer = null;
	this._slideSetup(true);
	this._build();
	if (chatDisplay.lastFocused) {
		if (this._inRange(this.tabPos[chatDisplay.lastFocused])) {
			chatDisplay.refocus();
		} else {
			chatDisplay.lastFocused = null;
		}
	}
	this._doSync();
}, next:function () {
	if (this.numNext <= 0) {
		return;
	}
	this.shift(this.numShift);
}, prev:function () {
	if (this.numPrev <= 0) {
		return;
	}
	this.shift(-this.numShift);
}};
if (window.Bootloader) {
	Bootloader.done(["js/f051yxtp6i0owg0o.pkg.js"]);
}

